package com.culture.config.service.impl;

import javax.annotation.Resource;

import com.culture.config.common.util.BeanUtil;
import com.culture.config.common.util.ExceptionUtil;
import com.culture.config.component.JobScheduleWorker;
import com.culture.config.dao.entity.JobInfo;
import com.culture.config.dao.mapper.JobMapper;
import com.culture.config.model.po.JobAddPO;
import com.culture.config.model.po.JobPagePO;
import com.culture.config.model.po.JobSchedulePO;
import com.culture.config.model.po.JobStatusUpdatePO;
import com.culture.config.model.po.JobUpdatePO;
import com.culture.config.model.vo.JobVO;
import com.culture.config.service.JobService;
import com.culture.config.util.CronUtil;
import com.culture.config.wrapper.JobWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class JobServiceImpl implements JobService{
    @Resource
    private JobMapper jobMapper;
    @Autowired
    private JobScheduleWorker jobScheduleWorker;

    @Override
    public void add(JobAddPO jobAddPO) {   
        CronUtil.validExpression(jobAddPO.getCron()); 
        JobInfo newJob = JobWrapper.wrapJobAdd(jobAddPO);           
        int ret = this.jobMapper.add(newJob);
        log.info("add new job:{} - {}",ret,newJob);
        this.jobScheduleWorker.jobSchedule();
    }

    @Override
    public void update(JobUpdatePO jobUpdatePO) {
        CronUtil.validExpression(jobUpdatePO.getCron());            
        JobInfo jobInfo = getAndValidateJobInfo(jobUpdatePO.getId());
        int ret = this.jobMapper.update(JobWrapper.wrapJobUpdate(jobInfo,jobUpdatePO));
        log.info("update job:{} - {}",ret,jobUpdatePO);
        this.jobScheduleWorker.jobSchedule();
    }

    @Override
    public Page<JobVO> page(JobPagePO jobPagePO) {
        PageMethod.startPage(jobPagePO.getPageNum(),jobPagePO.getPageSize());
        Page<JobInfo> pageJobInfo = this.jobMapper.page(JobWrapper.wrapJobQuery(jobPagePO));
        return BeanUtil.copyPageProperties(pageJobInfo, JobVO.class);
    }

    @Override
    public String schedule(JobSchedulePO jobSchedulePO) {
        JobInfo jobInfo = getAndValidateJobInfo(jobSchedulePO.getId());
        return this.jobScheduleWorker.runOnce(jobInfo);
    }

    @Override
    public void updateStatus(JobStatusUpdatePO jobStatusUpdatePO) {
        JobInfo jobInfo = getAndValidateJobInfo(jobStatusUpdatePO.getId());
        int ret = this.jobMapper.update(JobWrapper.wrapJobStatusUpdate(jobInfo,jobStatusUpdatePO));
        log.info("update job:{} - {}",ret,jobStatusUpdatePO);
        this.jobScheduleWorker.jobSchedule();
    }

    /**
     * getAndValidateJobInfo
     * @param jobId
     * @return
     */
    private JobInfo getAndValidateJobInfo(Long jobId){
        JobInfo jobInfo = this.jobMapper.get(jobId);
        ExceptionUtil.businessExceptionWhenNull(jobInfo, StringUtils.join("job not found with:",jobId));
        return jobInfo;
    }
    
}
